/**
 * @Author       : Mo 2427995270@qq.com
 * @Date         : 2024-04-28 11:47:15
 * @LastEditTime : 2025-02-18 11:37:33
 * @FilePath     : \KT-2043-APP\libs\mo_database.h
 * @Description  : 数据库
 * @Version      : V1.0
 * @History      :
 * @Note         :
 */
#ifndef __mo_database_H__
#define __mo_database_H__

/***************************************Includes***********************************/

#include "ff.h"
#include <time.h>


/*************************************Public Macros********************************/
#define MO_DB_VER 0

/**
 * @brief 获取早的数据时间
 * @note null
 */
#define mo_db_get_earliest_time(db) ((db)->info.time_earliest)
/**
 * @brief 获取最新的数据时间
 * @note null
 */
#define mo_db_get_latest_time(db) ((db)->info.time_latest)
/**
 * @brief 获取数据数量
 * @note null
 */
#define mo_db_get_quantity(db) ((db)->info.quantity)
/**
 * @brief 获取数据库版本
 * @note null
 */
#define mo_db_get_ver(db) ((db)->info.ver)
/**
 * @brief 获取最大的序号
 * @note null
 */
#define mo_db_get_snmax(db) ((db)->info.sn_max)
/***********************************Public Statement*******************************/

typedef struct {
    int ver;
    int quantity;
    int sn_max;
    int sector_size;      // 扇区大小 一条数据不能超过一个扇区大小-sizeof(mo_data_info_t)
    time_t time_earliest; // 最早时间
    time_t time_latest;   // 最新时间
} mo_db_info_t;

typedef struct {
    char db_path[FF_MAX_LFN]; // 数据库路径
    FIL fd;
    mo_db_info_t info; // 数据库信息
} mo_db_t;

/**
 * @brief 查询数据回调
 * @param  buf              存储数据的缓冲区，cb为NULL时该参数无效
 * @param  len              数据长度
 * @param  cnt              数据序号 1~
 * @param  usr_data         用户数据
 * @return int 0继续 -1中断查询
 * @note null
 */
typedef int (*mo_db_cb_t)(const void *buf, int len, int cnt, void *usr_data);

/***********************************Public Functions*******************************/

/**
 * @brief 打开数据库
 * @param  db
 * @param  db_path          数据库路径
 * @param  sector_size      扇区大小
 * @return int 0成功 -1失败
 * @note null
 */
int mo_db_open(mo_db_t *db, const char *db_path, int sector_size);
/**
 * @brief 关闭数据库
 * @param  db               
 * @return int 0成功 -1失败
 * @note null
 */
int mo_db_close(mo_db_t *db);
/**
 * @brief 重启数据库
 * @param  db               
 * @return int 0成功 -1失败
 * @note null
 */
int mo_db_reboot(mo_db_t *db);
/**
 * @brief 写入或修改数据
 * @param  db
 * @param  sn               序号起始1
 * @param  t                修改时间
 * @param  buf              待写入的数据
 * @param  size             数据长度
 * @return int 0成功 -1失败
 * @note null
 */
int mo_db_write(mo_db_t *db, int sn, time_t t, const void *buf, int size);
/**
 * @brief 读取数据
 * @param  db
 * @param  sn               序号起始1
 * @param  buf              存储待读取数据
 * @param  size             buf大小
 * @return int 0成功 -1失败
 * @note null
 */
int mo_db_read_sn(mo_db_t *db, int sn, void *buf, int size);
/**
 * @brief 根据开始和结束时间读取数据
 * @param  db
 * @param  time_s
 * @param  time_e
 * @param  offset           查询偏移量(跳过的数据量)
 * @param  reverse          0正序 1倒序
 * @param  buf              存储数据的缓冲区，cb为NULL时该参数无效
 * @param  size             要读数据的大小，一条的，cb为NULL时该参数无效
 * @param  usr_data         用户数据
 * @param  cb               接收数据的回调，给NULL可查询时间段的数据量, cb返回负数可中断查询
 * @return int 数据量 -1失败
 * @note null
 */
int mo_db_read_date(mo_db_t *db, time_t time_s, time_t time_e, int offset, int reverse, void *buf, int size, void *usr_data, mo_db_cb_t cb);
/**
 * @brief 删除数据
 * @param  db
 * @param  sn
 * @return int 0成功 -1失败
 * @note null
 */
int mo_db_remove(mo_db_t *db, int sn);
/**
 * @brief 删除所有数据
 * @param  db
 * @return int 0成功 -1失败
 * @note null
 */
int mo_db_clear(mo_db_t *db);

/***************************************Public Variables**********************************/


#endif
/* [] END OF FILE */
